package com.sooth.system.user.service;

import cn.dev33.satoken.secure.BCrypt;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.dream.boot.impl.ServiceImpl;
import com.dream.system.config.Page;
import com.sooth.common.dream.model.PageModel;
import com.sooth.system.dept.service.ISysDeptService;
import com.sooth.system.dept.view.SysDeptBo;
import com.sooth.system.user.mapper.SysUserMapper;
import com.sooth.system.user.table.SysUserPost;
import com.sooth.system.user.table.SysUserRole;
import com.sooth.system.user.view.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@RequiredArgsConstructor
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserVo, SysUserBo> implements ISysUserService {
    private final SysUserMapper userMapper;

    private final ISysDeptService deptService;

    private final ISysUserRoleService userRoleService;

    private final ISysUserPostService userPostService;

    @Value("${user.password.defaultValue}")
    private String defaultValue;

    @Override
    public SysUserVo queryUserByUserName(String userName, String tenantId) {
        return userMapper.queryUserByUserName(userName, tenantId);
    }

    @Override
    public Integer updateLoginInfo(String userName, String loginIp) {
        return userMapper.updateLoginInfo(userName, loginIp);
    }

    @Override
    public SysUserBo selectById(Object id) {
        SysUserBo sysUserBo = super.selectById(id);
        if (sysUserBo != null) {
            SysUserRoleDto userRoleDto = new SysUserRoleDto();
            userRoleDto.setUserId(sysUserBo.getId());
            List<SysUserRole> userRoles = userRoleService.selectList(userRoleDto);
            if (CollUtil.isNotEmpty(userRoles)) {
                sysUserBo.setRoleIds(userRoles.stream().map(SysUserRole::getRoleId).collect(Collectors.toList()));
            }
            SysUserPostDto userPostDto = new SysUserPostDto();
            userPostDto.setUserId(sysUserBo.getId());
            List<SysUserPost> sysUserPosts = userPostService.selectList(userPostDto);
            if (CollUtil.isNotEmpty(sysUserPosts)) {
                sysUserBo.setPostIds(sysUserPosts.stream().map(SysUserPost::getPostId).collect(Collectors.toList()));
            }
        }
        return sysUserBo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insert(SysUserBo sysUserBo) {
        String password = sysUserBo.getPassword();
        if (StrUtil.isEmpty(password)) {
            password = defaultValue;
        }
        password = BCrypt.hashpw(password);
        sysUserBo.setPassword(password);
        super.insertFetchKey(sysUserBo);
        handleRoleAndPost(sysUserBo);
        return 1;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateById(SysUserBo sysUserBo) {
        int count = super.updateById(sysUserBo);
        handleRoleAndPost(sysUserBo);
        return count;
    }

    private void handleRoleAndPost(SysUserBo sysUserBo) {
        SysUserRoleVo userRole = new SysUserRoleVo();
        userRole.setUserId(sysUserBo.getId());
        userRole.setRoleIds(sysUserBo.getRoleIds());
        userRoleService.save(userRole);
        SysUserPostVo userPost = new SysUserPostVo();
        userPost.setUserId(sysUserBo.getId());
        userPost.setPostIds(sysUserBo.getPostIds());
        userPostService.save(userPost);
    }

    @Override
    public Page<SysUserVo> queryPage(SysUserDto user, PageModel pageModel) {
        Long deptId = user.getDeptId();
        if (deptId != null && deptId > 0) {
            List<Long> deptIds = deptService.selectDeptIdsByParentId(deptId);
            user.setDeptIds(deptIds);
        }
        Page<SysUserVo> page = super.selectPage(user, pageModel);
        Collection<SysUserVo> rows = page.getRows();
        if (CollUtil.isNotEmpty(rows)) {
            Map<Long, String> deptMap = new HashMap<>();
            for (SysUserVo userVo : rows) {
                deptId = userVo.getDeptId();
                String deptName = deptMap.get(deptId);
                if (deptName == null) {
                    SysDeptBo dept = deptService.selectById(deptId);
                    if (dept != null) {
                        deptName = dept.getDeptName();
                    }
                }
                userVo.setDeptName(deptName);
            }
        }
        return page;
    }

    @Override
    public SysUserVo queryNickName(Long userId) {
        return userMapper.queryNickName(userId);
    }

}
